package org.tangerinejunction.imstats.util;

/**
 * A cycle refers to a well-defined repeated subdivision of time,
 * such as days of the week or months of the year.  Cycles can
 * help us see patterns beyond mere trends.
 * 
 * @author meganthorsen
 */
public class Cycle 
{
	public static final Cycle DAY_OF_WEEK = 
		new Cycle("Day of Week", Increment.WEEK, Increment.DAY, 
				new String[] {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"});
	
	public static final Cycle MONTH_OF_YEAR = 
		new Cycle("Month of Year", Increment.YEAR, Increment.MONTH,
				new String[] {"January", "February", "March", "April", "May", "June",
				"July", "August", "September", "October", "November", "December"});
	
	private String name;
	private Increment cycleLength;
	private Increment bucketSize;
	private String[] bucketNames;
	private int numBuckets;
	
	/**
	 * 
	 * @param name			the name of the Cycle, for display purposes
	 * @param cycleLength	the length of the Cycle
	 * @param bucketSize	the size of the Cycle's buckets
	 * @param bucketNames	the names of the Cycle's buckets, for display purposes
	 */
	public Cycle(String name, Increment cycleLength, Increment bucketSize, String[] bucketNames)
	{
		this.name = name;
		this.cycleLength = cycleLength;
		this.bucketSize = bucketSize;
		this.bucketNames = bucketNames;
		int remainingDays = cycleLength.numDays;
		int remainingMonths = cycleLength.numMonths;
		int remainingYears = cycleLength.numYears;
		numBuckets = 0;
		while (remainingDays > 0 || remainingMonths > 0 || remainingYears > 0)
		{
			// TODO: make this work correctly for non-day-sized buckets
			remainingDays -= bucketSize.numDays;
			remainingMonths -= bucketSize.numMonths;
			remainingYears -= bucketSize.numYears;
			// TODO: fix this magic number!
			if (remainingDays <= -30)
			{
				remainingDays = 0;
				remainingMonths--;
			}
			else if (remainingMonths <= -12)
			{
				remainingMonths = 0;
				remainingYears--;
			}
			numBuckets++;
		}
	}
	
	/**
	 * 
	 * @return	the name of this Cycle
	 */
	public String getName()
	{
		return name;
	}
	
	/**
	 * 
	 * @return	the length of this Cycle, e.g. a week for days of the week
	 */
	public Increment getCycleLength()
	{
		return cycleLength;
	}
	
	/**
	 * 
	 * @return	the size of this Cycle's buckets, e.g. a day for days of the week
	 */
	public Increment getBucketSize()
	{
		return bucketSize;
	}
	
	/**
	 * 
	 * @return	the names of this Cycle's buckets
	 */
	public String[] getBucketNames()
	{
		return bucketNames;
	}
	
	/**
	 * 
	 * @return	the number of buckets in this Cycle
	 */
	public int getBucketCount()
	{
		return numBuckets;
	}
	
	public String toString()
	{
		return name;
	}
}
